package com.guoheng.hazard.sys.service.impl.entpr;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.guoheng.hazard.common.base.Result;
import com.guoheng.hazard.common.constant.CommonConstants;
import com.guoheng.hazard.common.enums.ErrorCodeEnum;
import com.guoheng.hazard.common.util.StringUtils;
import com.guoheng.hazard.sys.mapper.entpr.EntprBasicExamineMapper;
import com.guoheng.hazard.sys.mapper.entpr.EntprBasicInfoMapper;
import com.guoheng.hazard.sys.mapper.hazard.MonitorSensorMapper;
import com.guoheng.hazard.sys.model.dto.entpr.*;
import com.guoheng.hazard.sys.model.entity.entpr.EntprBasicExamine;
import com.guoheng.hazard.sys.model.entity.entpr.EntprBasicInfo;
import com.guoheng.hazard.sys.model.entity.hazard.MonitorSensor;
import com.guoheng.hazard.sys.service.entpr.EntprBasicInfoService;
import com.guoheng.hazard.sys.service.impl.LoginServiceImpl;
import org.springframework.beans.BeanUtils;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;


/**
 * 类功能描述:　EntprBasicInfoServiceImpl
 *
 * @author fbl
 * @date 2019-45-11 15:45
 */
@Service
public class EntprBasicInfoServiceImpl implements EntprBasicInfoService {

    @Resource
    EntprBasicInfoMapper entprBasicInfoMapper;

    @Resource
    MonitorSensorMapper monitorSensorMapper;

    @Resource
    EntprBasicExamineMapper entprBasicExamineMapper;

    @Resource
    LoginServiceImpl loginService;


    @Override
    public Result getEntprBasicInfo(Long entprId) {
        EntprBasicInfo entprBasicInfo = entprBasicInfoMapper.getEntprBasicInfoById(entprId);
        EntprBasicInfoSelectDTO entprBasicInfoSelectDTO = new EntprBasicInfoSelectDTO();
        BeanUtils.copyProperties(entprBasicInfo, entprBasicInfoSelectDTO);
        String entprScope = entprBasicInfo.getEntprScope();
        loginService.transitionEntprScope(entprScope,entprBasicInfoSelectDTO);
        return Result.success(entprBasicInfoSelectDTO);
    }

    @Override
    public Result getEntprBasicInfos(String entprName, Integer pageNum, Integer pageSize) {
        PageHelper.startPage(pageNum, pageSize);
        List<EntprBasicInfo> entprBasicInfos = entprBasicInfoMapper.getAllEntprBasicInfo(entprName);
        PageInfo<EntprBasicInfo> entprBasicInfoPageInfo = new PageInfo<>(entprBasicInfos);
        return Result.success(entprBasicInfoPageInfo);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Result addEntprBasicInfo(EntprBasicInfoAddInDTO entprBasicInfoAddInDTO) {
        EntprBasicInfo entprBasicInfo = new EntprBasicInfo();
        BeanUtils.copyProperties(entprBasicInfoAddInDTO, entprBasicInfo);
        if (entprBasicInfoAddInDTO.getEntprScope() != null) {
            List<EntprScopeDTO> entprScopes = entprBasicInfoAddInDTO.getEntprScope();
            String entprScope = JSON.toJSONString(entprScopes);
            entprBasicInfo.setEntprScope(entprScope);
        }
        try {
            // 新增企业信息
            int insert = entprBasicInfoMapper.insertEntprBasicInfo(entprBasicInfo);
            if (insert == CommonConstants.DataBaseOperationStatus.IS_FAILURE) {
                throw new RuntimeException();
            }
            // 企业名称必须唯一
        } catch (DuplicateKeyException e) {
            return Result.failure(ErrorCodeEnum.DATA_ENTERPRISE_NAME_DUPLICATE);
        }
        return Result.success();
    }

    @Override
    public Result updateEntprBasicInfo(Long entprId, EntprBasicInfoUpdateInDTO entprBasicInfoUpdateInDTO) {
        EntprBasicInfo entprBasicInfo = new EntprBasicInfo();
        entprBasicInfo.setId(entprId);
        BeanUtils.copyProperties(entprBasicInfoUpdateInDTO, entprBasicInfo);
        if (entprBasicInfoUpdateInDTO.getEntprScope() != null) {
            List<EntprScopeDTO> entprScopes = entprBasicInfoUpdateInDTO.getEntprScope();
            String entprScope = JSON.toJSONString(entprScopes);
            entprBasicInfo.setEntprScope(entprScope);
        }
        try {
            entprBasicInfoMapper.updateEntprBasicInfoById(entprBasicInfo);
        } catch (DuplicateKeyException e) {
            return Result.failure(ErrorCodeEnum.DATA_ENTERPRISE_NAME_DUPLICATE);
        }
        return Result.success();
    }

    @Override
    public Result deleteEntprBasicInfo(Long entprId) {
        entprBasicInfoMapper.deleteEntprBasicInfoById(entprId);
        return Result.success();
    }

    @Override
    public Result searchEntprBasicInfo(String entprName, Integer reviewStatus, Integer pageNum, Integer pageSize) {
        if (pageSize == 0) {
            List<EntprBasicInfo> entprBasicInfos = entprBasicInfoMapper.searchEntprBasicInfo(entprName, reviewStatus);
            List<EntprBasicInfoSelectDTO> result = toJsonArray(entprBasicInfos, new ArrayList<EntprBasicInfoSelectDTO>());
            PageInfo<EntprBasicInfoSelectDTO> entprBasicInfoPageInfo = new PageInfo<>(result);
            return Result.success(entprBasicInfoPageInfo);
        }
        PageHelper.startPage(pageNum, pageSize);
        List<EntprBasicInfo> entprBasicInfos = entprBasicInfoMapper.searchEntprBasicInfo(entprName, reviewStatus);
        List<EntprBasicInfoSelectDTO> result = toJsonArray(entprBasicInfos, new ArrayList<EntprBasicInfoSelectDTO>());
        PageInfo<EntprBasicInfoSelectDTO> entprBasicInfoPageInfo = new PageInfo<>(result);
        return Result.success(entprBasicInfoPageInfo);
    }

    @Override
    public Result statisticsEntprBasicInfo() {
        // 查询所有企业信息
        List<EntprBasicInfo> entprBasicInfos = entprBasicInfoMapper.getAllEntprBasicInfo(null);

        // 使用流做统计示例：统计企业标准化等级
        //Map<Integer, Long> collect = entprBasicInfos.stream().filter(e -> e.getStandLevel() != null).collect(Collectors.groupingBy(EntprBasicInfo::getStandLevel, Collectors.counting()));

        // 统计信息
        StatisticsEntprDTO statisticsEntprDTO = statisticsEntprScale(entprBasicInfos);
        return Result.success(statisticsEntprDTO);
    }

    @Override
    public Result lastExamine(Long entprId) {
        // 企业最近一次申请记录信息
        LastExamineDTO lastExamineDTO = new LastExamineDTO();
        EntprBasicExamine lastExamine = entprBasicExamineMapper.getLastExamine(entprId);
        EntprBasicInfo entprBasicInfoById = entprBasicInfoMapper.getEntprBasicInfoById(entprId);
        lastExamineDTO.setEntprName(entprBasicInfoById.getEntprName());
        if(lastExamine != null){
            BeanUtils.copyProperties(lastExamine,lastExamineDTO);
            return Result.success(lastExamineDTO);
        }
        return Result.success(lastExamineDTO);
    }

    /**
     * 方法功能描述: 统计企业规模
     *
     * @param entprBasicInfos 企业基本信息
     * @return StatisticsEntprBasicInfoDTO
     */
    private StatisticsEntprDTO statisticsEntprScale(List<EntprBasicInfo> entprBasicInfos) {
        // 统计企业规模
        ArrayList<Integer> entprScale = new ArrayList<>();
        entprBasicInfos.forEach(e -> {
            entprScale.add(e.getEntprScale());
        });
        Map<Integer, Double> scaleMap = new HashMap<>();
        setMap(entprScale,scaleMap);
        ArrayList<StatisticsEntprScaleDTO> statisticsEntprScaleDTOS = new ArrayList<>();
        for (Map.Entry<Integer, Double> entprScaleMap : scaleMap.entrySet()) {
            StatisticsEntprScaleDTO statisticsEntprScaleDTO = new StatisticsEntprScaleDTO();
            statisticsEntprScaleDTO.setEntprScale(entprScaleMap.getKey());
            statisticsEntprScaleDTO.setEntprNum(entprScaleMap.getValue().intValue());
            statisticsEntprScaleDTOS.add(statisticsEntprScaleDTO);
        }

        // 统计标准化等级
        ArrayList<Integer> standLevel = new ArrayList<>();
        entprBasicInfos.forEach(e -> {
            standLevel.add(e.getStandLevel());
        });
        Map<Integer, Double> standLevelMap = new HashMap<>();
        setMap(standLevel,standLevelMap);
        ArrayList<StatisticsEntprStandLevelDTO> statisticsEntprStandLevelDTOS = new ArrayList<>();
        for (Map.Entry<Integer, Double> levelMap : standLevelMap.entrySet()) {
            StatisticsEntprStandLevelDTO statisticsEntprStandLevelDTO = new StatisticsEntprStandLevelDTO();
            statisticsEntprStandLevelDTO.setStandLevel(levelMap.getKey());
            statisticsEntprStandLevelDTO.setEntprNum(levelMap.getValue().intValue());
            statisticsEntprStandLevelDTOS.add(statisticsEntprStandLevelDTO);
        }

        // 统计企业经济类型
        ArrayList<Integer> ecoTypes = new ArrayList<>();
        entprBasicInfos.forEach(e -> {
            ecoTypes.add(e.getEcoType());
        });
        Map<Integer, Double> ecoTypeMap = new HashMap<>();
        setMap(ecoTypes,ecoTypeMap);

        ArrayList<StatisticsEntprEcoDTO> statisticsEntprEcoDTOS = new ArrayList<>();
        for (Map.Entry<Integer, Double> ecoMap : ecoTypeMap.entrySet()) {
            StatisticsEntprEcoDTO statisticsEntprEcoDTO = new StatisticsEntprEcoDTO();
            statisticsEntprEcoDTO.setEntprEcoType(ecoMap.getKey());
            // 小数精确两位
            DecimalFormat df = new DecimalFormat("#0.000000");
            Double majorHazardRation = ecoMap.getValue() / ecoTypes.size();
            statisticsEntprEcoDTO.setEntprEcoRatio(Double.valueOf(df.format(majorHazardRation)));
            statisticsEntprEcoDTO.setEntprNum(ecoMap.getValue().intValue());
            statisticsEntprEcoDTOS.add(statisticsEntprEcoDTO);
        }
        StatisticsEntprDTO statisticsEntprDTO = new StatisticsEntprDTO();
        statisticsEntprDTO.setStatisticsEntprScaleDTOS(statisticsEntprScaleDTOS);
        statisticsEntprDTO.setStatisticsEntprStandLevelDTOS(statisticsEntprStandLevelDTOS);
        statisticsEntprDTO.setStatisticsEntprEcoDTOS(statisticsEntprEcoDTOS);
        return statisticsEntprDTO;
    }

    private void setMap(List<Integer> integerList,Map<Integer, Double> maps ){
        for (Integer type : integerList) {
            //定义一个计数器，用来记录重复数据的个数
            Double i = 1.0;
            if (maps.get(type) != null) {
                i = maps.get(type) + 1;
            }
            if (type == null) {
                continue;
            }
            maps.put(type, i);
        }
    }
    /**
     * 厂区范围转换jsonArray
     *
     * @param entprBasicInfos          企业信息
     * @param entprBasicInfoSelectDTOS 企业查询数据层
     * @return List<EntprBasicInfoSelectDTO>
     */
    private List<EntprBasicInfoSelectDTO> toJsonArray(List<EntprBasicInfo> entprBasicInfos, List<EntprBasicInfoSelectDTO> entprBasicInfoSelectDTOS) {
        for (EntprBasicInfo entprBasicInfo : entprBasicInfos) {
            EntprBasicInfoSelectDTO entprBasicInfoSelectDTO = new EntprBasicInfoSelectDTO();
            BeanUtils.copyProperties(entprBasicInfo, entprBasicInfoSelectDTO);
            String entprScope = entprBasicInfo.getEntprScope();
            if (StringUtils.isNotEmpty(entprScope)) {
                entprScope = "{\"data\":" + entprScope + "}";
                JSONObject jsonObject = JSON.parseObject(entprScope);
                JSONArray jsonArray = jsonObject.getJSONArray("data");
                List<EntprScopeDTO> entprScopeDTOS = jsonArray.toJavaList(EntprScopeDTO.class);
                entprBasicInfoSelectDTO.setEntprScope(entprScopeDTOS);
            }
            entprBasicInfoSelectDTOS.add(entprBasicInfoSelectDTO);
        }
        return entprBasicInfoSelectDTOS;
    }

    private Integer totalSensor(Long entprId, Integer sensorType) {
        List<MonitorSensor> sensorByType = monitorSensorMapper.getSensorByType(entprId, null, sensorType);
        return sensorByType.size();
    }

}

